/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package compilador;

import java.io.Reader;

/**
 *
 * @author Melinton
 */
public class Lexer implements ITokenTypes
{
    
    //--------------------------------------------------------------------------
    // ATRIBUTOS
    //--------------------------------------------------------------------------    
    private CharBuffer input;
    private static final int LOOKAHEAD_DEPTH = 1;
    
    //--------------------------------------------------------------------------
    // CONSTRUCTOR
    //--------------------------------------------------------------------------    
    public Lexer (Reader f)
    {
        input = new CharBuffer(f, LOOKAHEAD_DEPTH);
    }
    
    //--------------------------------------------------------------------------
    // METODOS
    //--------------------------------------------------------------------------
    private int LA(int i) { return input.LA(i); }
    private void consume() { input.consume(); }
    private void match(int c) { consume(); }
    
    public Token identifier() 
    {
        StringBuffer s = new StringBuffer();
        while ( Character.isLetter((char)LA(1)) ) 
        {
            s.append((char)LA(1));
            consume();
        }
        String id = s.toString();
        if ( id.equals("COMPILER") )
            return new Token(KW_COMPILER, "COMPILER");
        else if(id.equals("CHARACTERS"))
            return new Token(KW_CHARACTERS, "CHARACTERS");
        else if(id.equals("KEYWORDS"))
            return new Token(KW_KEYWORDS, "KEYWORDS");
        else if(id.equals("TOKENS"))
            return new Token(KW_TOKENS, "TOKENS");
        else if(id.equals("PRODUCTIONS"))
            return new Token(KW_PRODUCTIONS, "PRODUCTIONS");
        return new Token(IDENTIFIER, id);
    }
    
    public Token comment() 
    {
        StringBuffer s = new StringBuffer();
        match('#');
        while ( LA(1) != '.' && LA(2) != ')') 
        {
            s.append((char)LA(1));
            consume();
        }
        return new Token(COMMENT, s.toString());
    }    
    
    public Token getToken() 
    {
        for( ; ; )
        {
            if (LA(1)==' ' || LA(1)=='\t')
                consume();
            else if ( Character.isLetter((char)LA(1)) )
                return identifier();                
            else if ( LA(1)=='(' && LA(2)=='.' ) 
                return comment();        
            else if ( LA(1)=='=') 
            {
                consume();
                return new Token(EQUALS, "=");
            }
            else if ( LA(1)=='\n' ) 
            {
                consume();
                return new Token(NEWLINE, "\n");
            }
            else if ( LA(1)=='(' ) 
            {
                consume();
                return new Token(LPAREN, "(");
            }
            else if ( LA(1)==')' ) 
            {
                consume();
                return new Token(RPAREN, ")");
            }
            else if ( LA(1)==-1 )         
                return new Token(EOF, "<eof>");        

            return null;
        }
    }    
    
}
